package labox.innovation.gameserver.templates.item;

import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javolution.util.FastList;
import labox.innovation.config.Config;
import labox.innovation.gameserver.model.L2ItemInstance.ItemGradeType;
import labox.innovation.gameserver.skills.Stats;
import labox.innovation.gameserver.skills.funcs.AttributeStringSplice;
import labox.innovation.util.Rnd;

/**
 * ��Ʒ�� ������� ϵͳ
 * @author zjj
 *
 */
public class ItemRandAttribute extends ItemBouns {
	
	static Logger _log = LoggerFactory.getLogger(ItemRandAttribute.class.getName());
	
	protected String _randAttri=""; //�������ֵ. �������е�������� �� ����ֵ. pdef:20. ���ڴ��ֶβ���Ƶ���ĸ��£����ұȽ�С����������ʹ����String��
	
	public String get_randAttri() {
		return _randAttri;
	}
	public void set_randAttri(String randAttri) {
		_randAttri = randAttri;
	}

	protected List<Stats> _randStats;
	
	protected String _attributeStr; //���������ַ�  
	
	protected boolean _needUpdateString; //�Ƿ��������������
	
//	protected Func[] _allfuncs;
	
	protected final float _itemlvlfactor = 0.1f; //װ���ȼ�ϵ��
	protected final int _itemlvlconstfactor = 30; //װ����ϵ��
	protected final float _itemfactormin = 0.1f;  //��С��������ϵ��
	protected final float _itemfactormax = 0.25f; //��󸽼�����ϵ��
	
	
	
	protected final int   _itempowerfac  = 1;     //��������ϵ��
	protected final int   _itemwitfac  = 1;     //��������ϵ��
	protected final int   _itemdexfac  = 1;     //��������ϵ��
	protected final int   _itemwisfac  = 1;     //��������ϵ��
	protected final int   _itemconfac  = 1;     //��������ϵ��
	protected final int   _itemhpmax  = 15;     //�������ֵ����ϵ��
	protected final int   _itemmpmax  = 20;     //ħ�����ֵ����ϵ��
	protected final int   _itempatk  = 3;     //�﹥����ϵ��
	protected final int   _itemmatk  = 3;     //ħ������ϵ��
	
	// ��Ʒ�������� ϵ��
	// �����Щϵ�� �������Ӧ������ֵ
	enum ItemFactor{
		
		STR(1), //����
		CON(1), //����
		DEX(1), //����
		INT(1), //����
		MEN(1), //����
		
		PowerAtk(3),//�﹥  ͬʱӰ��������
		MagicAtk(3),//ħ��  ͬʱӰ��������
		
		maxHp(15),//�������ֵ����ϵ��
		maxMp(20);//ħ�����ֵ����ϵ��
		
		int _factor;
		
		ItemFactor( int factor)
		{
			_factor = factor;
		}
		
		public int getFactor()
		{
			return _factor;
		}
		
	}
	
	/**
	 *  Ϊ�ϳ�װ��ʱ ��Ӹ������Զ� ʹ��
	 */
	public ItemRandAttribute()
	{
		_itemBounsType = ItemBounsType.RAND_ATTRIBUTES;
	}
	
	/**
	 *  ������ݿ�ָ�ʱ��  �����ַ��е����� ��ֵ
	 *  TODO: �����
	 * @param attriBute
	 */
	public ItemRandAttribute(String attriBute )
	{
		
	}
	/**
	 *   Ϊ��Ʒ���ʱ�� �������� �� ���ƶ�ʹ��
	 * @param attriStr ���Ƶ����������ַ�
	 * @param itemGrade ��Ʒ Ʒ��
	 * itemLvl : ��Ʒ�ȼ�
	 * attritype : �����������
	 */
	public ItemRandAttribute(String attriStr, String attritype, int itemGrade,int itemLvl, int weight)
	{
		_itemBounsType = ItemBounsType.RAND_ATTRIBUTES;
		createRandAttri( attriStr, attritype, itemGrade, itemLvl, weight );
	}
	
	/**
	 * ����������ֵ
	 * @param attriStr ���������ַ�(���� �������� ��ֵ)
	 * @param attritype ��������
	 * @param itemGrade ��Ʒ Ʒ��
	 * @param itemLvl ��Ʒ�ȼ�
	 * @param weight ��ƷȨֵ(��ͬ��λ�� ��Ʒ��ռȨֵ��һ��)
	 */
	protected void createRandAttri(String attriStr, String attritype, int itemGrade, int itemLvl ,int weight)
	{
		int imakeNums = 0;  //��¼���������� �� �ֶε� ����
		
		//������� ���Ժ�ֵ��  ��ôֱ����� ��Щ��������
		if( attriStr != null )
		{
			String[] attri = attriStr.split(",");
			for( String str:attri )
			{
				String[] attrivalue = str.split(":");
				int value = 0;
				
				Stats stat = Stats.valueOfXml( attrivalue[0] );
				
				//���ָ���� ���Ƶ����Ե�ֵ
				if( attrivalue.length >= 2 )
				{
//					_randAttri = _randAttri + str + ",";
					value = Integer.parseInt(attrivalue[1]);
					addAttriValue(stat, value);
				}

				
//				addFuncs( stat, value );
//				addAttribute( stat.ordinal(), value );	
//				addRandStats(stat);
				
				imakeNums++;
				
			}
			
		}// end if( attriStr != null )
		
		int nums = 0;
		try {	
			nums = ItemGradeType.values()[itemGrade].getRandAttiNum();	
		} catch (Exception e) {
			_log.error( "�������ƷƷ��", Config.SERVER_ID, e);
		}

		//��� �����㹻�Ķ��� ������ ����Ҫ����������������
		nums = nums - imakeNums;
		if( nums <= 0 )
		{
			return;
		}
		
		//�Ѷ��Ƶ� �����������
		if( attritype != null )
		{
			String[] attri = attritype.split(",");
			
			for( String str:attri )
			{
				Stats stat = Stats.valueOfXml( str );
				
				int value = 0;

				value = getRandAttriValue(str, itemLvl, weight);
//				_randAttri = _randAttri + str + ":"+ value + ",";		
				
//				addFuncs( stat, value );
//				addAttribute( stat.ordinal(), value );
//				addRandStats(stat);
				addAttriValue(stat, value);
				
				nums--;
				if( nums <= 0 )
				{
					break;
				}
				
			}
			
			attri = null;
			
		}// end if( attriStr != null )
		
		
		//��� �������ֵ ������ ��������е� ĳ���������
		//ָ����ӵ����Ը���
		addItemAttri( nums, itemLvl, weight );
		
	}// end createRandAttri
	
	/**
	 *  ���Ӹ�������
	 * @param attritype : ������������
	 * @param itemGrade : ��ƷƷ�ʵȼ�
	 * @param itemLvl : ��Ʒ�ȼ�
	 * @param weight  : ��ƷȨ��
	 */
	public boolean addItemAttri( String attritype, int itemGrade, int itemLvl ,int weight )
	{
		//���������ظ��ĸ�������
		
		return addItemAttri( Stats.valueOfXml( attritype ), itemGrade , itemLvl, weight );
		
	}
	
	/**
	 *  ���Ӹ�������
	 * @param stat : ������������
	 * @param itemGrade : ��ƷƷ�ʵȼ�
	 * @param itemLvl : ��Ʒ�ȼ�
	 * @param weight  : ��ƷȨ��
	 * @return
	 */
	public boolean addItemAttri( Stats stat, int itemGrade, int itemLvl ,int weight )
	{
		if( hasAttri( stat ) ) //������������������ ��ôֱ�ӷ���
		{
			return false;
		}
		
		//����������ֵ
		int value = getRandAttriValue( stat.getValue(), itemLvl, weight );
		if( value == 0 ){
			value = 1;
		}
//		_randAttri =_randAttri + stat.getValue() + ":" + value + ",";
//		addFuncs( stat, value );
//		addAttribute( stat.ordinal(), value );
//		addRandStats(stat);
		
		addAttriValue(stat, value);
		
		return true;
		
	}// end addItemAttri()
	
	/**
	 *  ���Ӹ������� �� ֵ
	 *  ������� רΪ��ݿ��ʹ��
	 * @param stat ����
	 * @param val  ֵ
	 */
	public void addItemAttriFromDB( int stat, int val )
	{
		if( Stats.values()[stat] == Stats.MAGIC_ATTACK_ATTI || Stats.values()[stat] == Stats.MAX_MAGIC_ATTACK 
				|| Stats.values()[stat] == Stats.MIN_MAGIC_ATTACK ){
			
			if( _attributes.containsKey( Stats.MAGIC_ATTACK_ATTI  ) ){
				return;
			}
			
			addAttriValue( Stats.MAGIC_ATTACK_ATTI, val );
			
		}
		else if( Stats.values()[stat] == Stats.POWER_ATTACK_ATTI || Stats.values()[stat] == Stats.MAX_POWER_ATTACK 
				|| Stats.values()[stat] == Stats.MIN_POWER_ATTACK ){
			
			
			if( _attributes.containsKey( Stats.POWER_ATTACK_ATTI  ) ){
				return;
			}
			
			addAttriValue( Stats.POWER_ATTACK_ATTI, val );
			
			
		}else
			
			addAttriValue( Stats.values()[stat], val );
		
	}
	
	/**
	 * �Ƿ����������������
	 * @param stat
	 * @return
	 */
	protected boolean hasAttri( Stats stat )
	{
		if( _randStats != null )
		{
			for( Stats temp:_randStats )
			{
				
				if( stat == Stats.MAGIC_ATTACK_ATTI ){
					
					if( temp == Stats.MAX_MAGIC_ATTACK || temp == Stats.MIN_MAGIC_ATTACK ){
						
						return true;
						
					}
					
				}
				
				if( stat == Stats.POWER_ATTACK_ATTI ){
					
					if( temp == Stats.MAX_POWER_ATTACK || temp == Stats.MIN_POWER_ATTACK ){
						
						return true;
						
					}
					
				}
				
				if( temp == stat )// ���������Ѵ���  �������ͬ��ĸ�������
				{
					return true;
				}
				
			}
			
		}// end if( _randStats != null )
		
		return false;
	}
	
	protected boolean hasAttri( String stat )
	{
		if( stat != null )
		{
			return hasAttri( Stats.valueOfXml(stat) );
		}
		
		return false;
	}
	
	
	/**
	 *  ָ����Ӹ������Ե� ����
	 * @param attrinum : ��ӵĸ������Ը���
	 * @param itemLvl : ��Ʒ�ȼ�
	 * @param weight : ��ƷȨ��ֵ
	 */
	public void addItemAttri( int attrinum, int itemLvl, int weight )
	{
		if( attrinum <= 0 )
		{
			return;
		}
		
		String rndattri = getConfigRandAttri();
		if( rndattri == null )
		{
			_log.warn("�������Ե������ַ�Ϊ��", Config.SERVER_ID);
			return;
		}

		String []rnd = rndattri.split(",");
		
		List<Integer> indexList = new FastList<Integer>();
		for( int i=0; i < rnd.length; i++ )
		{
			indexList.add( i );
		}
		
		while( attrinum > 0 )
		{
			int size = indexList.size();
			if( size <= 0 )
			{
				break;
			}
			
			int index = Rnd.get( size );
			
			if( addItemAttri( rnd[index], 0, itemLvl, weight) )
			{
				indexList.remove( (Integer)index );
				attrinum--;
			}
			
		}// end
		
	}
	
	
	/**
	 * ����������� ״̬
	 * @param stat
	 */
	protected void addRandStats( Stats stat )
	{
		if( _randStats == null )
		{
			_randStats = new FastList<Stats>();
		}
		
		_randStats.add( stat );
	}
	
	/**
	 *  ��� ���״̬����
	 * @return
	 */
	public List<Stats> getRandStats()
	{
		return _randStats;
	}
	
	/*
	 *  ������� �е� һ���������
	 *  ��ʽΪ : Str;Int;Dex;Hp;Mp
	 */
	protected String getConfigRandAttri()
	{
		return Config.ITEMRANDATTRIBUE;
	}
	
	/**
	 *  ��� ������Ե�ֵ
	 *   ������Ե�ֵ ��Ҫ�� ��������ȡֵ���л��
	 * @param stats : ����
	 * itemLvl : ��Ʒ�ȼ�
	 * @param weight : ��ƷȨֵ
	 * @return
	 */
	protected int getRandAttriValue( String stats, int itemLvl, int weight )
	{
		float base = itemLvl * 2;
		
		int min = (int)( base * ItemFactor.valueOf( stats ).getFactor() * _itemfactormin );
		int max = (int)( base * ItemFactor.valueOf( stats ).getFactor() * _itemfactormax );
		
		return ( Rnd.get(min, max) * weight ) / 100;

	}
	
	/**
	 *  ��Ӹ������� �� ֵ
	 * @param stat
	 * @param value
	 */
	private void addAttriValue(Stats stat, int value)
	{
		if( stat == null )
		{
			_log.warn( "������������Ϊ��", Config.SERVER_ID);
		}
		
		_needUpdateString = true;
//		_randAttri =_randAttri + stat.getValue() + ":" + value + ",";
		if( stat == Stats.MAGIC_ATTACK_ATTI ){
			
			addAttribute( Stats.MAGIC_ATTACK_ATTI.ordinal(), value );
			addRandStats( Stats.MAGIC_ATTACK_ATTI);
			
			addFuncs(  Stats.MAX_MAGIC_ATTACK, value );			
			addFuncs(  Stats.MIN_MAGIC_ATTACK, value );
//			addAttribute( Stats.MIN_MAGIC_ATTACK.ordinal(), value );
//			addRandStats( Stats.MIN_MAGIC_ATTACK );
			
			
		}else if( stat == Stats.POWER_ATTACK_ATTI ){
			
			addAttribute( Stats.POWER_ATTACK_ATTI.ordinal(), value );
			addRandStats( Stats.POWER_ATTACK_ATTI);
			
			addFuncs(  Stats.MAX_POWER_ATTACK, value );
			addFuncs(  Stats.MIN_POWER_ATTACK, value );
//			addAttribute( Stats.MIN_POWER_ATTACK.ordinal(), value );
//			addRandStats( Stats.MIN_POWER_ATTACK );
			
			
		}else{
			
			addFuncs( stat, value );
			addAttribute( stat.ordinal(), value );
			addRandStats(stat);
			
		}

	}
	
	@SuppressWarnings("unused")
	private void addAttriValue( String stat, int value )
	{
		if( stat != null )
		{
			addAttriValue( Stats.valueOfXml( stat ), value );
		}
	}
	
	@Override
	public String getAttributeDescribe() {
		// TODO Auto-generated method stub
		if( ( _attributeStr == null && _attributes.size()  > 0 ) || _needUpdateString )
		{
			_attributeStr = "<a>��������:</a><br/>" + AttributeStringSplice.getInstance().getAttributeString(_attributes );
		}
		
		return _attributeStr;

	}

	
	/**
	 *  ��� �������Ե� ����״̬���� �� ֵ 
	 * @return
	 */
	public Map<Integer, Integer> getAttriMap()
	{
		return _attributes;
	}
	
	public int getAttriNums()
	{
		return _randStats == null? 0:_randStats.size();
	}
	
	/**
	 * ����Ϊ�˲���
	 */
	public void onlyForTest()
	{
		System.out.println("��Ʒ�ĸ�������:" + _randAttri);
	}

}
